package com.crl.gen.service;

import com.cars.util.date.DateUtil;
import com.cars.util.file.FileUtil;
import com.cars.util.string.StringUtil;
import com.crl.gen.dao.GenConfigDao;
import com.crl.gen.dao.GenFieldDao;
import com.crl.gen.dao.GenTableDao;
import com.crl.gen.model.GenConfig;
import com.crl.gen.model.GenField;
import com.crl.gen.model.GenTable;
import com.crl.gen.vo.GenCreateSearchVO;
import com.google.common.base.CaseFormat;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description:代码生成
 * @author: 孔垂云
 * @version: 1.0
 * @date: 2020/7/25 14:16
 */
@Service
public class GenCreateService {
    @Autowired
    private GenConfigDao genConfigDao;
    @Autowired
    private GenTableDao genTableDao;
    @Autowired
    private GenFieldDao genFieldDao;
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    String firstCode = "";
    String secondCode = "";
    String firstCodeUpper = "";
    String secondCodeUpper = "";
    String firstName = "";
    String secondName = "";
    String javaPackage = "";
    String model = "";//
    String modelLower = "";//

    /**
     * 获取数据库类型
     *
     * @param tableId
     * @return
     */
    private int getDatabaseType(int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        GenConfig genConfig = genConfigDao.get(genTable.getAuthorId());
        int databaseType = genConfig.getDatabaseType();//数据库类型
        return databaseType;
    }

    /**
     * 判断要生成的文件是否存在
     *
     * @param tableId
     * @param type
     * @return
     */
    public boolean checkFileExist(int authorId, int tableId, int type) {
        GenTable genTable = genTableDao.get(tableId);
        GenConfig genConfig = genConfigDao.get(authorId);//获取配置文件
        String parentBizPath = genConfig.getJavaBizFilepath() + File.separator + transJavaPackage(genTable.getJavaPackage()) + File.separator;
        String parentApiPath = genConfig.getJavaApiFilepath() + File.separator + transJavaPackage(genTable.getJavaPackage()) + File.separator;
        String filename = "";
        boolean flag = false;
        if (type == 1) {// Model
            filename = parentBizPath + genTable.getFirstCode() + File.separator + "model" + File.separator + model + ".java";
        } else if (type == 2) {// vo
            filename = parentBizPath + genTable.getFirstCode() + File.separator + "vo" + File.separator + model + "SearchVO.java";
        } else if (type == 3) {// dto
            filename = parentBizPath + genTable.getFirstCode() + File.separator + "dto" + File.separator + model + "DTO.java";
        } else if (type == 4) {// dao
            filename = parentBizPath + genTable.getFirstCode() + File.separator + "dao" + File.separator + model + "Dao.java";
        } else if (type == 5) {// service
            filename = parentBizPath + genTable.getFirstCode() + File.separator + "service" + File.separator + model + "Service.java";
        } else if (type == 6) {// controller
            filename = parentApiPath + genTable.getFirstCode() + File.separator + "controller" + File.separator + model + "Controller.java";
        }
        flag = FileUtil.checkFileExist(filename);
        return flag;
    }


    /**
     * 生成DTO代码
     *
     * @return
     */
    public String createDTOCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);

        List<GenField> listFields = genFieldDao.list(tableId);
        StringBuffer fields = new StringBuffer("");
        for (GenField genField : listFields) {
            fields.append("\t@ApiModelProperty(\"" + genField.getFieldname() + "\")\r\n");//swagger的api描述
            //格式校验
            //是否为空,只有字符串才能判断
            if (genField.getIsBlank() == 0 && genField.getType() == 1) {
                if (genField.getFieldname().equals(genTable.getPkField())) {
                    fields.append("\t@NotEmpty(groups = {UpdateValidGroup.class})\r\n");
                } else {
                    fields.append("\t@NotEmpty\r\n");
                }
            }
            //字段长度,如果是字符串，长度最大值为输入长度，如果为数字，则为字段长度
            if (genField.getType() == 1) {
                fields.append("\t@Length(max = " + genField.getInputLength() + ")\r\n");
            }

            fields.append("\tprivate " + getFieldsType(genField.getType(), genField.getLength()) + " " + toCamel(genField.getFieldcode()) + "; //" + genField.getFieldname() + "\r\n\r\n");
        }

        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("fields", fields.toString());

        String createContent = generateModelContent("dto.java.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成VO代码
     *
     * @return
     */
    public String createVOCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);
        String isPageExtend = "";//是否分页代码，extends
        List<GenField> listFields = genFieldDao.list(tableId);
        String fields = "";
        for (GenField genField : listFields) {
            if (genField.getIsSearchField() == 1) {
                fields += "\tprivate " + getFieldsType(genField.getType(), genField.getLength()) + " " + toCamel(genField.getFieldcode()) + "; //" + genField.getFieldname() + "\r\n";
            }
        }

        if (genTable.getIsPage() == 1) {//是否分页
            isPageExtend = "extends BasePageSearchVO ";
        }

        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("isPageExtend", isPageExtend);//是否分页
        mapParam.put("fields", fields);

        String createContent = generateModelContent("vo.java.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成Model代码
     *
     * @return
     */
    public String createModelCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);
        List<GenField> listFields = genFieldDao.list(tableId);
        String fields = "";
        for (GenField genField : listFields) {
            fields += "\tprivate " + getFieldsType(genField.getType(), genField.getLength()) + " " + toCamel(genField.getFieldcode()) + "; //" + genField.getFieldname() + "\r\n";
        }

        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("fields", fields);

        String createContent = generateModelContent("model.java.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成Dao代码
     *
     * @return
     */
    public String createDaoCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);

        List<GenField> listFields = genFieldDao.list(tableId);
        StringBuffer fields = new StringBuffer("");
        String listField = "", viewField = "";//定义查看字段和列表字段
        String insertFields = "", insertFieldsValues = "", updateFields = "";//定义新增和修改字段
        String pkFieldType = "";//主键类型
        String searchCode = "";//查询条件
        int databaseType = this.getDatabaseType(tableId);
        //根据主键字段生成方式，来判断怎么生成的主键，如果为自增，oracle从序列获取，mysql不加该字段，如果为人工设值，直接取所取的值即可
        for (GenField genField : listFields) {
            fields.append("\tprivate " + getFieldsType(genField.getType(), genField.getLength()) + " " + toCamel(genField.getFieldcode()) + "; //" + genField.getFieldname() + "\r\n");
            //新增字段
            if (databaseType == 1) {
                insertFields += genField.getFieldcode() + ",";
            } else if (databaseType == 2) {
                if (!genField.getFieldcode().equalsIgnoreCase(genTable.getPkField())) {
                    insertFields += genField.getFieldcode() + ",";
                }
            }
            if (databaseType == 1) {//Oracle
                if (!genField.getFieldcode().equalsIgnoreCase(genTable.getPkField())) {
                    insertFieldsValues += ":" + toCamel(genField.getFieldcode()) + ",";
                } else {
                    insertFieldsValues += "seq_" + genTable.getTablename() + ".nextval,";
                }
            } else if (databaseType == 2) {//mysql，自增主键不用设值
                if (!genField.getFieldcode().equalsIgnoreCase(genTable.getPkField())) {
                    insertFieldsValues += ":" + toCamel(genField.getFieldcode()) + ",";
                }
            }

            //修改字段
            if (!genField.getFieldcode().equalsIgnoreCase(genTable.getPkField())) {//非主键加入到修改字段
                updateFields += genField.getFieldcode() + "=:" + toCamel(genField.getFieldcode()) + ",";
            }

            if (genField.getIsListField() == 1 || genField.getFieldcode().equals(genTable.getPkField())) {//列表字段或者主键，都要展示
                listField += genField.getFieldcode() + ",";
            }
            viewField += genField.getFieldcode() + ",";//查看字段
            if (genField.getFieldcode().equalsIgnoreCase(genTable.getPkField())) {//主键
                pkFieldType = getFieldsType(genField.getType(), genField.getLength());
            }

//            if (StringUtil.isNotNullOrEmpty(dicProvinceSearchVO.getProvinceName())) {
//                sql += " AND province_name LIKE '%'||:provinceName||'%' ";
//            }
            if (genField.getIsSearchField() == 1) {//是查询条件
                if (genField.getType() == 1) {//字符串
                    String search = "";
                    search = "if (StringUtil.isNotNullOrEmpty(" + modelLower + "SearchVO.get" + upper(toCamel(genField.getFieldcode())) + "())) {\r\n";
                    search += "\t\t\tsql += \" AND " + genField.getFieldcode() + " =:" + toCamel(genField.getFieldcode()) + " \";\r\n";
                    search += "\t\t}";
                    searchCode += search;
                } else if (genField.getType() == 2) {//数字
                    String search = "";
                    search = "if (" + modelLower + "SearchVO.get" + upper(toCamel(genField.getFieldcode())) + "()!=null) {\r\n";
                    search += "\t\t\tsql += \" AND " + genField.getFieldcode() + " =:" + toCamel(genField.getFieldcode()) + " \";\r\n";
                    search += "\t\t}";
                    searchCode += search;
                }

            }
        }

        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("databaseType", databaseType);//数据库类型
        mapParam.put("tablename", genTable.getTablename());//数据表名
        mapParam.put("pkField", genTable.getPkField());//主键
        mapParam.put("pkFieldCamel", toCamel(genTable.getPkField()));//主键驼峰
        mapParam.put("pkFieldType", pkFieldType);//主键类型
        mapParam.put("insertFields", StringUtil.subTract(insertFields));
        mapParam.put("insertFieldsValues", StringUtil.subTract(insertFieldsValues));
        mapParam.put("updateFields", StringUtil.subTract(updateFields));

        mapParam.put("listField", StringUtil.subTract(listField));//查询字段
        mapParam.put("viewField", StringUtil.subTract(viewField));//查看字段
        mapParam.put("orderField", genTable.getOrderField());//排序字段
        mapParam.put("searchCode", searchCode);//查询字段

        mapParam.put("fields", fields.toString());
        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("dao.java.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成service代码
     *
     * @return
     */
    public String createServiceCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);

        List<GenField> listFields = genFieldDao.list(tableId);
        StringBuffer fields = new StringBuffer("");
        String pkFieldType = "";
        for (GenField genField : listFields) {
            if (genField.getFieldcode().equalsIgnoreCase(genTable.getPkField())) {//主键
                pkFieldType = getFieldsType(genField.getType(), genField.getLength());
            }
        }

        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("pkField", genTable.getPkField());//主键
        mapParam.put("pkFieldCamel", toCamel(genTable.getPkField()));//主键驼峰
        mapParam.put("pkFieldType", pkFieldType);//主键类型
        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("service.java.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 设置默认的值
     *
     * @param genTable
     */
    private void setDefaultValue(GenTable genTable) {
        firstCode = genTable.getFirstCode();
        secondCode = genTable.getSecondCode();
        firstCodeUpper = upper(firstCode);
        secondCodeUpper = upper(secondCode);
        firstName = genTable.getFirstName();
        secondName = genTable.getSecondName();
        javaPackage = genTable.getJavaPackage();
        model = firstCodeUpper + secondCodeUpper;//定义model
        modelLower = firstCode + secondCodeUpper;//定义model首字母小写
    }

    /**
     * 生成Controller代码
     *
     * @return
     */
    public String createControllerCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);

        List<GenField> listFields = genFieldDao.list(tableId);
        StringBuffer fields = new StringBuffer("");
        String pkFieldType = "";
        for (GenField genField : listFields) {
            if (genField.getFieldcode().equals(genTable.getPkField())) {//主键
                pkFieldType = getFieldsType(genField.getType(), genField.getLength());
            }
        }

        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("pkField", genTable.getPkField());//主键
        mapParam.put("pkFieldCamel", toCamel(genTable.getPkField()));//主键驼峰
        mapParam.put("pkFieldType", pkFieldType);//主键类型
        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("controller.java.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 根据类型返回
     *
     * @param authorId
     * @param tableId
     * @param type
     * @return
     */
    public String createCode(int authorId, int tableId, int type) {
        if (type == 1) {
            return this.createModelCode(authorId, tableId);
        } else if (type == 2) {
            return this.createVOCode(authorId, tableId);
        } else if (type == 3) {
            return this.createDTOCode(authorId, tableId);
        } else if (type == 4) {
            return this.createDaoCode(authorId, tableId);
        } else if (type == 5) {
            return this.createServiceCode(authorId, tableId);
        } else if (type == 6) {
            return this.createControllerCode(authorId, tableId);
        }
        //vue 部分
        else if (type == 11) {
            return this.createApiCode(authorId, tableId);
        } else if (type == 12) {
            return this.createIndexCode(authorId, tableId);
        } else if (type == 13) {
            return this.createComponentCode(authorId, tableId);
        } else if (type == 14) {
            return this.createRouterCode(authorId, tableId);
        }
        return "";
    }

    /**
     * 生成文件
     *
     * @param genCreateSearchVO
     * @return
     */
    public int createFile(GenCreateSearchVO genCreateSearchVO) {
        int authorId = genCreateSearchVO.getAuthorId();
        int tableId = genCreateSearchVO.getTableId();
        int type = genCreateSearchVO.getType();

        String code = "";
        String filePath = "";
        GenTable genTable = genTableDao.get(tableId);
        GenConfig genConfig = genConfigDao.get(authorId);//获取配置文件
        //创建对应的package目录
        FileUtil.createFileDir(genConfig.getJavaBizFilepath() + File.separator + transJavaPackage(genTable.getJavaPackage()));
        String parentBizPath = genConfig.getJavaBizFilepath() + File.separator + transJavaPackage(genTable.getJavaPackage()) + File.separator;
        String parentApiPath = genConfig.getJavaApiFilepath() + File.separator + transJavaPackage(genTable.getJavaPackage()) + File.separator;
        String vuePath = genConfig.getVueFilepath();
        FileUtil.createFileDir(parentBizPath + genTable.getFirstCode() + File.separator + "model" + File.separator);
        FileUtil.createFileDir(parentBizPath + genTable.getFirstCode() + File.separator + "vo" + File.separator);
        FileUtil.createFileDir(parentBizPath + genTable.getFirstCode() + File.separator + "dto" + File.separator);
        FileUtil.createFileDir(parentBizPath + genTable.getFirstCode() + File.separator + "dao" + File.separator);
        FileUtil.createFileDir(parentBizPath + genTable.getFirstCode() + File.separator + "service" + File.separator);
        FileUtil.createFileDir(parentApiPath + genTable.getFirstCode() + File.separator + "controller" + File.separator);
        //生成vue对应的文件夹
        FileUtil.createFileDir(vuePath + File.separator + "api" + File.separator + genTable.getFirstCode());  //api
        FileUtil.createFileDir(vuePath + File.separator + "views" + File.separator + genTable.getFirstCode() + File.separator + genTable.getSecondCode() + File.separator + "components");  //vue

        if (type == 1) {
            code = this.createModelCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "model" + File.separator + model + ".java";
            FileUtil.writeFile(filePath, code);
        } else if (type == 2) {
            code = this.createVOCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "vo" + File.separator + model + "SearchVO.java";
            FileUtil.writeFile(filePath, code);
        } else if (type == 3) {
            code = this.createDTOCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "dto" + File.separator + model + "DTO.java";
            FileUtil.writeFile(filePath, code);
        } else if (type == 4) {
            code = this.createDaoCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "dao" + File.separator + model + "Dao.java";
            FileUtil.writeFile(filePath, code);
        } else if (type == 5) {
            code = this.createServiceCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "service" + File.separator + model + "Service.java";
            FileUtil.writeFile(filePath, code);
        } else if (type == 6) {
            code = this.createControllerCode(authorId, tableId);
            filePath = parentApiPath + genTable.getFirstCode() + File.separator + "controller" + File.separator + model + "Controller.java";
            FileUtil.writeFile(filePath, code);
        } else if (type == 0) {//生成所有的
            code = this.createModelCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "model" + File.separator + model + ".java";
            FileUtil.writeFile(filePath, code);
            code = this.createVOCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "vo" + File.separator + model + "SearchVO.java";
            FileUtil.writeFile(filePath, code);
            code = this.createDTOCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "dto" + File.separator + model + "DTO.java";
            FileUtil.writeFile(filePath, code);
            code = this.createDaoCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "dao" + File.separator + model + "Dao.java";
            FileUtil.writeFile(filePath, code);
            code = this.createServiceCode(authorId, tableId);
            filePath = parentBizPath + genTable.getFirstCode() + File.separator + "service" + File.separator + model + "Service.java";
            FileUtil.writeFile(filePath, code);
            code = this.createControllerCode(authorId, tableId);
            filePath = parentApiPath + genTable.getFirstCode() + File.separator + "controller" + File.separator + model + "Controller.java";
            FileUtil.writeFile(filePath, code);
        }
        //vue部分
        else if (type == 11) {//vue api接口
            code = this.createApiCode(authorId, tableId);
            filePath = vuePath + File.separator + "api" + File.separator + genTable.getFirstCode() + File.separator + genTable.getSecondCode() + ".js";
            FileUtil.writeFile(filePath, code);
        } else if (type == 12) {//vue 列表页面
            code = this.createIndexCode(authorId, tableId);
            filePath = vuePath + File.separator + "views" + File.separator + genTable.getFirstCode() + File.separator + genTable.getSecondCode() + File.separator + "index.vue";
            FileUtil.writeFile(filePath, code);
        } else if (type == 13) {//vue 增删改页面
            //生成Components
            code = this.createComponentCode(authorId, tableId);
            filePath = vuePath + File.separator + "views" + File.separator + genTable.getFirstCode() + File.separator + genTable.getSecondCode() + File.separator + "components" + File.separator + model + "Detail.vue";
            FileUtil.writeFile(filePath, code);
            if (genTable.getIsAdd() == 1) {
                code = this.createInfoCode(authorId, tableId, 1);
                filePath = vuePath + File.separator + "views" + File.separator + genTable.getFirstCode() + File.separator + genTable.getSecondCode() + File.separator + "add.vue";
                FileUtil.writeFile(filePath, code);
            }
            if (genTable.getIsUpdate() == 1) {
                code = this.createInfoCode(authorId, tableId, 2);
                filePath = vuePath + File.separator + "views" + File.separator + genTable.getFirstCode() + File.separator + genTable.getSecondCode() + File.separator + "update.vue";
                FileUtil.writeFile(filePath, code);
            }
            if (genTable.getIsView() == 1) {
                code = this.createInfoCode(authorId, tableId, 3);
                filePath = vuePath + File.separator + "views" + File.separator + genTable.getFirstCode() + File.separator + genTable.getSecondCode() + File.separator + "info.vue";
                FileUtil.writeFile(filePath, code);
            }
        }
        return 1;
    }

    /**
     * 把java package转换为具体的文件路径
     *
     * @param javaPackage
     * @return
     */
    private String transJavaPackage(String javaPackage) {
        String filePath = "";
        String path[] = javaPackage.split("\\.");
        for (String str : path) {
            filePath += str + File.separator;
        }
        return filePath;
    }


    /**
     * 生成建表脚本
     *
     * @param authorId
     * @return
     */
    public String createTableSql(int authorId, int tableId) {
        String sql = "";
        GenTable genTable = genTableDao.get(tableId);
        List<GenField> listFields = genFieldDao.list(tableId);
        GenConfig genConfig = genConfigDao.get(authorId);
        if (genConfig.getDatabaseType() == 1) {
            sql = createOracleDB(listFields, genTable);
        } else if (genConfig.getDatabaseType() == 2) {
            sql = createMysqlDB(listFields, genTable);
        }
        return sql;
    }

    /**
     * 生成oracle 的建表脚本
     *
     * @param genTable
     * @param listField
     * @return
     */
    private String createOracleDB(List<GenField> listField, GenTable genTable) {
        String sql = "";
        sql += "DROP TABLE " + genTable.getTablename() + ";\r\n";
        sql += "CREATE TABLE " + genTable.getTablename() + "(\r\n";
        String fields = "";
        String fieldsComment = "";
        int i = 0;
        for (GenField genField : listField) {
            fields += "\t" + genField.getFieldcode() + " " + getDbType3(genField.getType(), genField.getLength(), genField.getPoint());
            if (i < listField.size() - 1) {
                fields += ",\r\n";
            }
            fieldsComment += "COMMENT ON COLUMN " + genTable.getTablename() + "." + genField.getFieldcode() + "  IS \'" + genField.getFieldname() + "\';\r\n";
            i++;
        }
//        fields = StringUtil.subTract(fields);
        sql += fields + "\r\n);\r\n\r\n";
        sql += "ALTER TABLE " + genTable.getTablename() + "  ADD CONSTRAINT PK_" + genTable.getTablename() + " PRIMARY KEY (" + genTable.getPkField() + ");";
        sql += "\r\n";
        sql += "\r\n";
        sql += "COMMENT ON TABLE " + genTable.getTablename() + " is \'" + genTable.getDescription() + "\';\r\n";
        sql += fieldsComment;
        return sql;
    }

    /**
     * 生成oracle 的建表脚本
     *
     * @param genTable
     * @param listField
     * @return
     */
    private String createMysqlDB(List<GenField> listField, GenTable genTable) {
        String sql = "";
        sql += "DROP TABLE IF EXISTS `" + genTable.getTablename() + "`;\r\n";
        sql += "CREATE TABLE `" + genTable.getTablename() + "` (\r\n";
        String fields = "";
        int i = 0;
        for (GenField genField : listField) {
//            `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',

            fields += "\t`" + genField.getFieldcode() + "` " + getDbType4(genField.getType(), genField.getLength(), genField.getPoint());
            if (genField.getFieldcode().equals(genTable.getPkField())) {
                fields += " AUTO_INCREMENT";
            }
            fields += " COMMENT '" + genField.getFieldname() + "'";
            fields += ",\r\n";
            i++;
        }
        fields += " PRIMARY KEY (`" + genTable.getPkField() + "`)";
//        fields = StringUtil.subTract(fields);
        sql += fields + "\r\n)";
        sql += "AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;";
        return sql;
    }

    /**
     * 设置默认的map
     *
     * @param mapParam
     */
    private void setDefaultMap(Map<String, Object> mapParam) {
        mapParam.put("firstCode", firstCode);
        mapParam.put("secondCode", secondCode);
        mapParam.put("firstCodeUpper", firstCodeUpper);
        mapParam.put("secondCodeUpper", secondCodeUpper);
        mapParam.put("firstName", firstName);
        mapParam.put("secondName", secondName);
        mapParam.put("javaPackage", javaPackage);
        mapParam.put("model", model);
        mapParam.put("modelLower", modelLower);
    }

    /**
     * 生成代码
     *
     * @param templateName
     * @param map
     * @param gen_id
     * @return
     */
    private String generateModelContent(String templateName, Map<String, Object> map, int gen_id) {
        GenConfig genConfig = genConfigDao.get(gen_id);
        map.put("authorName", genConfig.getAuthorName());// 用户
        map.put("date", DateUtil.getSystemTime());// 生成时间
        // 使用FreeMaker模板
        try {
            Configuration configuration = freeMarkerConfigurer.getConfiguration();
            configuration.setDirectoryForTemplateLoading(new File(genConfig.getCodemodelFilepath()));
            configuration.setDefaultEncoding("utf-8");
            Template t = configuration.getTemplate(templateName);
            return FreeMarkerTemplateUtils.processTemplateIntoString(t, map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 首字母变大写
    private String upper(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
     * 字段转成驼峰写法
     *
     * @param field
     * @return
     */
    private String toCamel(String field) {
        return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, field);
    }

    /**
     * 根据字段类型取得java类型
     *
     * @param type
     * @return
     */
    private String getFieldsType(int type, int length) {
        if (type == 1) {
            return "String";
        } else if (type == 2) {
            if (length <= 12) {
                return "Integer";
            } else {
                return "Long";
            }
        } else if (type == 3) {
            if (length < 13) {
                return "Float";
            } else {
                return "Double";
            }
        } else if (type == 4 || type == 5) {
            return "Date";
        } else {
            return "String";
        }
    }

    /**
     * 根据字段类型取得java类型,查询条件里用到
     *
     * @param type
     * @return
     */
    private String getFieldsType2(int type, int length) {
        if (type == 1) {
            return "String";
        } else if (type == 2) {
            if (length <= 12) {
                return "Integer";
            } else {
                return "Long";
            }
        } else if (type == 3) {
            if (length < 13) {
                return "Float";
            } else {
                return "Double";
            }
        } else {
            return "String";
        }
    }

    // Ext里面字段类型判断
    private String getFieldsType3(int type, int length) {
        if (type == 1) {
            return "string";
        } else if (type == 2) {
            if (length <= 12) {
                return "int";
            } else {
                return "long";
            }
        } else if (type == 3) {
            if (length < 13) {
                return "float";
            } else {
                return "double";
            }
        } else {
            return "string";
        }
    }

    /*
     * 数据库字段类型，Oracle type 1英文字符，2整数，3小数，4中文字符
     */
    private String getDbType3(int type, int length, int point) {
        if (type == 1) {
            return "VARCHAR2(" + length + ")";
        } else if (type == 2) {
            return "NUMBER(" + length + ")";
        } else if (type == 3) {
            return "NUMBER(" + length + "," + point + ")";
        } else if (type == 4) {
            return "Varchar2(" + length * 2 + ")";
        } else {
            return "";
        }
    }

    /**
     * * 数据库字段类型，Mysql type 1英文字符，2整数，3小数，4中文字符
     *
     * @param type
     * @param length
     * @param point
     * @return
     */
    private String getDbType4(int type, int length, int point) {
        if (type == 1) {
            return "Varchar(" + length + ")";
        } else if (type == 2) {
            if (length < 4) {
                return "tinyint";
            } else {
                return "int(" + length + ")";
            }
        } else if (type == 3) {
            return "float(" + length + "," + point + ")";
        } else if (type == 4) {
            return "date";
        } else if (type == 5) {
            return "datetime";
        } else {
            return "";
        }
    }


    /***************************生成Vue代码***************************/
    /**
     * 生成api接口代码
     *
     * @return
     */
    public String createApiCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);
        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("apiUrl", genTable.getApiUrl());//api Url的默认值
        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("api.js.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成Info代码
     *
     * @return
     */
    public String createInfoCode(int authorId, int tableId, int operaType) {
        //operaType：操作类型1新增，2修改，3查看
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);
        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        mapParam.put("operaType", operaType);//操作类型

        mapParam.put("apiUrl", genTable.getApiUrl());//api Url的默认值
        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("info.vue.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成表单组件vue代码
     *
     * @return
     */
    public String createComponentCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);
        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        StringBuilder formField = new StringBuilder("");//表单字段
        StringBuilder rules = new StringBuilder("");//表单校验
        String formFieldValue = "";//表单字段默认值
        List<GenField> listFields = genFieldDao.list(tableId);
        for (GenField genField : listFields) {
            String hidden = "";
            //如果是主键，且是自动生成的，该字段隐藏
            if (genField.getFieldcode().equals(genTable.getPkField())) {
                hidden = "hidden";
            }
            int maxLength = 0;//判断前端输入最大长度
            if (genField.getType() == 1) {
                maxLength = genField.getInputLength();
            } else {
                maxLength = genField.getLength();
            }
            formField.append(" <el-form-item label=\"" + genField.getFieldname() + "\" prop=\"" + toCamel(genField.getFieldcode()) + "\" " + hidden + ">\n" +
                    "        <el-input v-model=\"postForm." + toCamel(genField.getFieldcode()) + "\" clearable placeholder=\"" + genField.getFieldname() + "\" maxlength=\"" + maxLength + "\" :disabled=\"formDisabled\" />\n" +
                    "      </el-form-item>");
            formFieldValue += toCamel(genField.getFieldcode()) + ": null,";
            if (genField.getIsBlank() == 0 && !genField.getFieldcode().equals(genTable.getPkField())) {
                rules.append(toCamel(genField.getFieldcode()) + ": [{ required: true, trigger: 'blur', message: '" + genField.getFieldname() + "不能为空' }],");
            }
        }

        mapParam.put("formField", formField.toString());//表单字段
        mapParam.put("formFieldValue", StringUtil.subTract(formFieldValue));//表单字段默认值
        mapParam.put("rules", StringUtil.subTract(rules.toString()));//格式校验
        mapParam.put("pkFieldCamel", toCamel(genTable.getPkField()));//主键驼峰
        mapParam.put("apiUrl", genTable.getApiUrl());//api Url的默认值
        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("component.vue.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成路由代码
     *
     * @return
     */
    public String createRouterCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);
        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);

        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("router.js.fmt", mapParam, authorId);
        return createContent;
    }

    /**
     * 生成index Vue代码
     *
     * @return
     */
    public String createIndexCode(int authorId, int tableId) {
        GenTable genTable = genTableDao.get(tableId);
        this.setDefaultValue(genTable);
        Map<String, Object> mapParam = new HashMap<>();
        this.setDefaultMap(mapParam);
        StringBuilder searchField = new StringBuilder("");//查询条件
        StringBuilder listField = new StringBuilder("");//列表字段
        String searchFieldValue = "";//默认的查询条件赋值
        List<GenField> listFields = genFieldDao.list(tableId);
        for (GenField genField : listFields) {
            if (genField.getIsSearchField() == 1) {
                searchField.append("  <el-input\n" +
                        "            v-model=\"listQuery." + toCamel(genField.getFieldcode()) + "\"\n" +
                        "            placeholder=\"" + genField.getFieldname() + "\"\n" +
                        "            style=\"width: " + genField.getListWidth() + "px;\"/>");
                searchFieldValue += toCamel(genField.getFieldcode()) + ": null,";
            }
            if (genField.getIsListField() == 1) {
                listField.append("<el-table-column\n" +
                        "        prop=\"" + toCamel(genField.getFieldcode()) + "\"\n" +
                        "        label=\"" + genField.getFieldname() + "\"\n" +
                        "        width=\"" + genField.getListWidth() + "\"\n" +
                        "      />");
            }
        }

        mapParam.put("searchField", searchField.toString());//查询条件
        if (genTable.getIsPage() == 1) {//如果不分页的话，去掉最后一个逗号
            mapParam.put("searchFieldValue", searchFieldValue);//默认查询赋值
        } else {
            mapParam.put("searchFieldValue", StringUtil.subTract(searchFieldValue));//默认查询赋值
        }
        mapParam.put("listField", listField);//列表字段
        mapParam.put("pkFieldCamel", toCamel(genTable.getPkField()));//主键驼峰
        mapParam.put("apiUrl", genTable.getApiUrl());//api Url的默认值
        mapParam.put("isPage", genTable.getIsPage());// 是否分页
        mapParam.put("isAdd", genTable.getIsAdd());// 是否新增
        mapParam.put("isUpdate", genTable.getIsUpdate());// 是否修改
        mapParam.put("isDelete", genTable.getIsDelete());// 是否删除
        mapParam.put("isView", genTable.getIsView());// 是否查看
        String createContent = generateModelContent("index.vue.fmt", mapParam, authorId);
        return createContent;
    }
}
